<?php

namespace app\controllers;

use app\models\ApiResponseCode;
use app\models\Order;
use yii\base\ErrorException;
use yii\base\Exception;
use yii\web\Controller;

class InteralApiController extends Controller
{
    public $enableCsrfValidation = false;
    public $layout = false;

    private $_request = null;

    /**
     * 设置订单的配送单信息
     * 由业务系统主动调用此接口进行数据的写入
     * @return string
     */
    public function actionSetOrderDelivery()
    {
        $orderCode = $this->_getRequestValue('order_code');
        $orderDeliveryCode = $this->_getRequestValue('order_delivery_code');
        $logisticsCompany = $this->_getRequestValue('logistics_company');
        $logisticsCode = $this->_getRequestValue('logistics_code');
        $goodsList = $this->_getRequestValue('goods_list');

        $data = [
            'order_delivery_code' => $orderDeliveryCode,
            'order_code' => $orderCode,
            'logistics_company' => $logisticsCompany,
            'logistics_code' => $logisticsCode,
            'goods_list' => $goodsList
        ];

        $status = Order::setOrderDelivery($data);

        if ($status == 0) {
            return $this->renderJson();
        } else {
            return $this->renderJson(null, ApiResponseCode::OtherErrorCode, '设置订单配送单信息失败.');
        }
    }

    /**
     * 修改订单状态为"已完成"
     * @return string
     */
    public function actionSetOrderCompleted()
    {
        $orderCode = $this->_getRequestValue('order_code');

        $status = Order::setOrderCompleted($orderCode);

        if ($status == 0) {
            return $this->renderJson();
        } else {
            return $this->renderJson(null, ApiResponseCode::OtherErrorCode, '设置订单状态失败!');
        }
    }

    public function beforeAction($action)
    {
//        if (YII_DEBUG != true) {
        $auth = $this->_auth();
        if ($auth == false) {
            return false;
        }
//        }

        $this->_request = json_decode(file_get_contents("php://input"));
        return parent::beforeAction($action); // TODO: Change the autogenerated stub
    }

    /**
     * 重写基类runAction,已处理所有action异常
     * @param string $id
     * @param array $params
     * @return mixed|void
     */
    public function runAction($id, $params = [])
    {
        try {
            return parent::runAction($id, $params);
        } catch (ErrorException $ex) {
            return $this->_errorHandler($ex);
        } catch (Exception $ex) {
            return $this->_errorHandler($ex);
        } catch (\Exception $ex) {
            return $this->_errorHandler($ex);
        }
    }

    /**
     * 自定义的错误处理返回json
     * @param \Exception $ex
     * @return string
     */
    private function _errorHandler($ex)
    {
        if (YII_DEBUG == true) {
            return $this->renderJson(null, ApiResponseCode::ExceptionCode, ApiResponseCode::ExceptionMessage . ':' . $ex->getMessage());
        } else {
            return $this->renderJson(null, ApiResponseCode::ExceptionCode, ApiResponseCode::ExceptionMessage . ':' . $ex->getMessage());
        }
    }

    /**
     * 接口返回通用数据结构
     * @param array|mixed $data
     * @param int $status [0:success]
     * @param string $message
     * @return string
     */
    public function renderJson($data = null, $status = 0, $message = 'success')
    {
        $result = [
            'status' => $status,
            'message' => $message,
            'data' => $data
        ];

        return json_encode($result, true);
    }

    /**
     * 接口签名验证
     * @return bool
     */
    private function _auth()
    {
        // 缺少account参数
        $account = \Yii::$app->request->get('account');
        if ($account == null) {
            echo $this->renderJson(null, ApiResponseCode::AccountMissingCode, ApiResponseCode::AccountMissingMessage);  // 缺少账户信息 (1001)
            return false;
        }

        // 缺少timestamp参数
        $timestamp = \Yii::$app->request->get('timestamp');
        if ($timestamp == null) {
            echo $this->renderJson(null, ApiResponseCode::TimestampMissingCode, ApiResponseCode::TimestampMissingMessage);  // 缺少时间戳 (1002)
            return false;
        }

        // 缺少sign参数
        $sign = \Yii::$app->request->get('sign');
        if ($sign == null) {
            echo $this->renderJson(null, ApiResponseCode::SignMissingCode, ApiResponseCode::SignMissingMessage);  // 缺少签名信息 (1004)
            return false;
        }

        // timestamp过期
        if (abs(time() - $timestamp) > \Yii::$app->params['api.TimestampValidity']) {
            echo $this->renderJson(null, ApiResponseCode::TimestampInvalidCode, ApiResponseCode::TimestampInvalidMessage);  // 签名过期 (1003)
            return false;
        }

        // sign认证
        $token = $this->_getAccountToken();
        $authSign = hash_hmac('sha256', $account . $token . $timestamp, $token);
        if ($authSign != $sign) {
            echo $this->renderJson(null, ApiResponseCode::SignAuthFailedCode, ApiResponseCode::SignAuthFailedMessage);  // 签名认证失败 (1005)
            return false;
        }

        return true;
    }

    /**
     * 获取account的token
     * @return string
     */
    private function _getAccountToken()
    {
        $token = \Yii::$app->params['interal.api.IntegralHubToken'];
        return $token;
    }

    /**
     * 获取post传入进来的某个参数值
     * @param $request
     * @param string $paramName 参数名
     * @param null|string|int|float $defaultValue
     * @return mixed|null
     */
    private function _getRequestParamValue($request, $paramName, $defaultValue = null)
    {
        $returnValue = null;
        $request = (array)$request;
        if (isset($request[$paramName])) {
            $returnValue = $request[$paramName];
        }
        if ($returnValue == null) {
            if (isset($defaultValue)) {
                $returnValue = $defaultValue;
            } else {
                echo $this->renderJson(null, ApiResponseCode::ParamMissingCode, ApiResponseCode::ParamMissingMessage . ': ' . $paramName);
                exit;
            }
        }
        return $returnValue;
    }

    /**
     * 获取当前这次post传入进来的某个参数值
     * @param string $paramName 参数名
     * @param null|string|int|float $defaultValue
     * @return mixed|null
     */
    private function _getRequestValue($paramName, $defaultValue = null)
    {
        return $this->_getRequestParamValue($this->_request, $paramName, $defaultValue);
    }

    /**
     * 退货
     * @return string
     */
    public function actionBackOrderGoods()
    {
        $order_code = $this->_getRequestValue('order_code');
        $goods_code = $this->_getRequestValue('goods_code');
        $quantity = $this->_getRequestValue('quantity');


        if (empty($order_code) || empty($goods_code) || empty($quantity)) {
            return $this->renderJson(null, ApiResponseCode::ParamErrorCode, ApiResponseCode::ParamErrorMessage);
        }
        $data = null;
        $status = 0;
        $message = '';

        if (!Order::backOrderGoods($order_code, $goods_code, $quantity, $message)) {
            $status = 1;
        }

        return $this->renderJson($data, $status, $message);
    }

}